home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Carousel
/
CAROUSEL.cdr
/
mactosh
/
utilprn
/
hpdeskje.sit
/
HPDJet ƒ
/
PDEF4.c
< prev
next >
Wrap
C/C++ Source or Header
|
1989-04-02
|
37KB
|
1,306 lines
/* 02.04.1989 amn (latest edit) */
/* PDEF4.c - printer driver style and job dialog handler for Macintosh and HP DeskJet. */
/* Compiles into 'PDEF' resource, id 4, name ''. */
/* We cannot use any global variables in this code. However, the globals of the */
/* low-level driver (XPrint) are available thru the handle 'dCtlStorage' in the */
/* driver's device control entry. */
/* This resource is placed into the printer resource file */
/* 'HP DeskJet', type 'PRER', creator 's89^' as */
/* 'PDEF' 4 '' by 'PRER_Builder' utility program. This utility adds a small jump */
/* table in front of the code produced by LightspeedC. */
/* The procedures in this file generate print records for the printing application */
/* to be used in conjunction with our high-level driver ('PDEF' 0/'PDEF' 1&5). */
/* The print record data structure is exposed to applications, thus they may */
/* - synthetize it */
/* - reuse a record made by another driver */
/* - let us present a default print record */
/* - make modifications to it */
/* - etc. */
/* Fortunately, they must validate this record using 'PrValidate()'. */
/* ... */
/* Authors: Ari Mujunen (amn@hutcs.hut.fi) and Olli Arnberg (oar@hutcs.hut.fi). */
/* Copyright Ari Mujunen, Olli Arnberg 1989. */
/* You may redistribute the driver (=printer resource file, source files, */
/* documentation file(s), and the file 'Copyright and Source Offer') */
/* only _non-commercially_ and _in its entirety_. */
/* See the file 'Copyright and Source Offer' and/or documentation for details. */
/* Acknowledgements: Special thanks to Mr. Earle R. Horton for his 'Daisy' */
/* daisywheel printer driver and its source code published in 'MacTutor', Nov-Dec 1987. */
/* This driver served as a basis and inspiration for our work. It also */
/* proofed that a Macintosh printer driver can be done despite the lack of */
/* documentation from Apple. */
/* Change history: */
/* Version When Who Why */
/* 2.0 20.11.1988 amn Original rewrite. */
/* 21.11.1988 amn 'Other' paper size. */
/* 25.11.1988 amn Read the printed listing... */
/* 26.11.1988 amn Searching for some kind of memory overwrite. */
/* 27.11.1988 amn It wasn't here, it was in XPrint.c. */
/* 09.12.1988 amn Number fields in dialogs. */
/* 08.03.1989 amn, oar Help. */
/* 23.03.1989 amn, oar Allowing added dialog items to receive any keystroke. */
/* 25.03.1989 amn Enlarge/reduce percentages. */
/* 26.03.1989 amn Reframe OK-button when update messages arrive. */
/* 28.03.1989 amn Settable printer origin. */
/* 30.03.1989 amn, oar Fine-tuning hard-coded default print record. */
/* 31.03.1989 amn Setting permanent spool file flag. */
/* 2.1 02.04.1989 amn,oar Released version. */
#include "common_mac_includes.h"
/* Mac OS includes specific to this module: */
/* none yet */
#include "prglobals.h"
/* Paper size number is used to index the array of paper size descriptors */
/* in the resource 'PREC' 4. */
/* (Apple's drivers use 'PREC' 3, but some applications know what is there and */
/* try to supply more paper sizes by themselves. We would like to be able to */
/* emulate different page sizes using the same paper size -- this is why we don't */
/* use a similar PREC 3.) */
/* Add a number from each of the following three groups to get the correct number. */
#define PAPER_A4 0
#define PAPER_US_LETTER 1
#define PAPER_US_LEGAL 2
#define PAPER_ENVELOPE 3
#define PAPER_DEFAULT PAPER_A4
#define PAPER_MASK 0x0003
#define PRINTER_IMAGE 0
#define PRINTER_LQ 4
#define PRINTER_LASER 8
#define PRINTER_HPDESKJET 12
#define PRINTER_DEFAULT PRINTER_LASER
#define PRINTER_NUMBER_OF 4
#define PRINTER_MASK 0x000C
#define PIXELS_BEAUTIFUL 0
#define PIXELS_EXACT 16
#define PIXELS_DEFAULT PIXELS_BEAUTIFUL
#define PIXELS_NUMBER_OF 16
#define PIXELS_MASK 0x0010
/* Dialog id's and item numbers in resource file. */
/* Page setup (style) dialog: */
#define STYLEDIALOG (-8192)
#define STYLEHELPDIALOG (-8137)
#define HPICON 5
#define A4BUTTON 6
#define USLETTERBUTTON 7
#define USLEGALBUTTON 8
#define ENVELOPEBUTTON 9
#define OTHERBUTTON 10
#define EXACTBOX 11
#define APPLEWRITERBOX 12
#define IMAGEBUTTON 13
#define LQBUTTON 14
#define LASERBUTTON 15
#define PAPERWIDTHNUM 17
#define PAPERHEIGHTNUM 18
#define MARGINTOPNUM 20
#define MARGINLEFTNUM 21
#define TALLBUTTON 23
#define WIDEBUTTON 24
#define MARGINBOTTOMNUM 27
#define MARGINRIGHTNUM 28
#define RESVNUM 29
#define RESHNUM 30
#define STYLEHELPBUTTON 31
#define STYLESCALENUM 32
#define LASTSTYLEITEM 32
/* Printing (job) dialog: */
#define JOBDIALOG (-8191)
#define JOBHELPDIALOG (-8161)
#define DPI300BUTTON 3
#define DPI150BUTTON 4
#define DPI100BUTTON 5
#define DPI75BUTTON 6
#define DRAFTBUTTON 7
#define ALLBUTTON 8
#define RANGEBUTTON 9
#define FROMNUM 16
#define TONUM 18
#define COPIESNUM 20
#define AUTOMATICBUTTON 10
#define MANUALBUTTON 11
#define JOBHELPBUTTON 22
#define JOBSCALENUM 23
#define LASTJOBITEM 23
/* Types used in this module. */
/* This struct contains info from paper size description resource PREC 4. */
typedef struct tPaperSizeInfo {
int iVRes;
int iHRes;
Rect rPage;
Rect rPaper;
int iPageV;
int iPageH;
TFeed feed;
SignedByte fill;
} tPaperSizeInfo;
typedef struct tAllSizesInfo {
int iNumberOfItems;
tPaperSizeInfo sSizeInfo[1];
} tAllSizesInfo, **htAllSizesInfo;
/* Function prototypes. */
void main(int);
/* Fill default print record. */
pascal void myPrintDefault(THPrint);
/* Print style & job dialogs. */
pascal Boolean myPrStlDialog(THPrint);
pascal Boolean myPrJobDialog(THPrint);
/* Set up style/job dialog. */
pascal TPPrDlg myPrStlInit(THPrint);
pascal TPPrDlg myPrJobInit(THPrint);
TPPrDlg allocatePrDialog(void);
/* Print dialog supervisor. */
pascal Boolean myPrDlgMain(THPrint, ProcPtr);
/* Validate print record. */
pascal Boolean myPrValidate(THPrint);
/* Copy information set in job dialog. */
pascal void myPrJobMerge(THPrint, THPrint);
/* Filter dialog events. */
pascal Boolean myStyleFilter(TPPrDlg, EventRecord *, int *);
pascal Boolean myJobFilter(TPPrDlg, EventRecord *, int *);
/* ??? */
pascal void handleStyleItems(TPPrDlg, int);
void setPaperSizeFieldsInPrintRecord(TPPrDlg, THPrint);
void setOtherPaperSizeInDialog(TPPrDlg, THPrint);
pascal void handleJobItems(TPPrDlg, int);
/* Make a hard-coded default print record. */
void mkDefault(THPrint);
/* Is the print record valid ? */
Boolean isValid(THPrint);
Boolean isCorrectableAndWasUpdated(THPrint);
/* Paper sizes in 'PREC' 4 resource. */
int whichPaperSize(THPrint);
Boolean updatePaperSize(THPrint, int);
/* Dialog item handling. */
#define DIALOG_PTR_TYPE_TODAY TPPrDlg
#include "dialog_item_handling.h"
void blankStringItem(TPPrDlg, int);
/* Function definitions. */
void
main(routineSelector)
int routineSelector;
{
/* The jump table code inserted before our code resource by 'PRER_Builder' */
/* utility program pushes a word onto stack indicating which routine is called. */
/* We pop it off the stack and select an appropriate routine. */
switch(routineSelector) {
case 0:
asm {
unlk a6 ;; LSC generates an 'link' instruction to access parameters
move.l (a7)+, d0 ;; pop return address to our jump table code (discarded)
move.w (a7)+, d0 ;; pop argument 'routineSelector'
jmp myPrintDefault
}
case 1:
asm {
unlk a6
move.l (a7)+, d0
move.w (a7)+, d0
jmp myPrStlDialog
}
case 2:
asm {
unlk a6
move.l (a7)+, d0
move.w (a7)+, d0
jmp myPrJobDialog
}
case 3:
asm {
unlk a6
move.l (a7)+, d0
move.w (a7)+, d0
jmp myPrStlInit
}
case 4:
asm {
unlk a6
move.l (a7)+, d0
move.w (a7)+, d0
jmp myPrJobInit
}
case 5:
asm {
unlk a6
move.l (a7)+, d0
move.w (a7)+, d0
jmp myPrDlgMain
}
case 6:
asm {
unlk a6
move.l (a7)+, d0
move.w (a7)+, d0
jmp myPrValidate
}
case 7:
asm {
unlk a6
move.l (a7)+, d0
move.w (a7)+, d0
jmp myPrJobMerge
}
} /* switch */
/* We should not arrive here; Printing Manager has called a non-existent routine. */
SysError(5); /* check bounds trap ??? */
} /* main */
/*
This function fills a print record with defaults. The default values are stored in the printer
resource file, in PREC 0. This is easy. Then we check the fields of the print record for
anything obviously illegal. If the default print record contains stuff that is bad, then we
correct it and update the copy in the printer resource file. This should never happen, but
some wise guy with a copy of ResEdit and more brains than sense may think he knows more than
we do.
*/
pascal void
myPrintDefault(hPrint)
THPrint hPrint;
{
THPrint theDefault;
HNoPurge(hPrint); /* hopefully it is not nil */
theDefault = (THPrint)GetResource('PREC', 0);
if (theDefault == nil) {
/* Add a new copy of the hard-coded print record as defaults. */
mkDefault(hPrint);
if ((theDefault = (THPrint)NewHandle((long)(sizeof(TPrint)))) != nil) {
/* Under MultiFinder this should probably have been allocated from the System Heap. */
int saveRefNum;
/* New default PREC is added to printer resource file */
saveRefNum = CurResFile();
UseResFile(
HomeResFile(
GetResource('PDEF', 4)
)
);
**theDefault = **hPrint;
AddResource(theDefault, 'PREC', 0, "\pDefault");
if (ResError() == noErr) {
WriteResource(theDefault);
HPurge(theDefault);
}
else {
DisposHandle(theDefault);
}
UseResFile(saveRefNum);
}
}
else {
LoadResource(theDefault);
HNoPurge(theDefault);
if (!isValid(theDefault)) {
if (!isCorrectableAndWasUpdated(theDefault)) /* either correct it... */
mkDefault(theDefault); /* ...or use hard-coded defaults */
ChangedResource(theDefault);
/* if (ResError()...; there is not much we could do */
WriteResource(theDefault);
} /* if not valid */
**hPrint = **theDefault;
HPurge(theDefault);
}
} /* myPrintDefault */
/* Print style dialog. */
pascal Boolean
myPrStlDialog(hPrint)
THPrint hPrint;
{
return(myPrDlgMain(hPrint, (ProcPtr)myPrStlInit));
}
/* Print job dialog. */
pascal Boolean
myPrJobDialog(hPrint)
THPrint hPrint;
{
return(myPrDlgMain(hPrint, (ProcPtr)myPrJobInit));
}
/* Style dialog initializer. */
pascal TPPrDlg
myPrStlInit(hPrint)
THPrint hPrint;
{
TPPrDlg tp;
int iPaperSize;
TPrint descaledPrintRecord;
TPPrint pointerToThePreviousPrintRecordToProduceAFakeHandle;
tp = allocatePrDialog();
(void)GetNewDialog(STYLEDIALOG, tp, (WindowPtr)(-1L));
/* We cannot determine if the resources were found or not (IM I-413). */
/* Oops, IM doesn't say anything about 'hPrint': it may be full of zeros */
/* or from another driver and it is most likely unvalidated. ??? */
/* Descale all rectangles accrding to printX[6] field. */
descaledPrintRecord = **hPrint;
{
Rect tr1, tr2;
if ((descaledPrintRecord.printX[6] < 25)
|| (descaledPrintRecord.printX[6] > 400))
descaledPrintRecord.printX[6] = 100;
tr1.top = 0;
tr1.left = 0;
tr1.bottom = tr1.right = descaledPrintRecord.printX[6];
tr2.top = 0;
tr2.left = 0;
tr2.bottom = tr2.right = 100;
MapRect(&(descaledPrintRecord.rPaper), &tr1, &tr2);
MapRect(&(descaledPrintRecord.prInfo.rPage), &tr1, &tr2);
ScalePt(&(descaledPrintRecord.prStl.iPageV), &tr1, &tr2); /* V&H = Point ! */
}
/* Determine the right paper size button by searching sizes in resource PREC 4: */
pointerToThePreviousPrintRecordToProduceAFakeHandle = &descaledPrintRecord;
iPaperSize = whichPaperSize(&pointerToThePreviousPrintRecordToProduceAFakeHandle);
if (iPaperSize < 0) {
/* 'Other' paper size. */
setOtherPaperSizeInDialog(tp, &pointerToThePreviousPrintRecordToProduceAFakeHandle);
}
else { /* standard size found */
int i;
/* Determine sheet size.*/
i = iPaperSize & PAPER_MASK;
pushRadioButton(tp, A4BUTTON+i, A4BUTTON, OTHERBUTTON);
/* Determine printer type.*/
i = iPaperSize & PRINTER_MASK;
if (i == PRINTER_HPDESKJET) {
forceValueToControls(tp, 0, APPLEWRITERBOX, APPLEWRITERBOX);
forceValueToControls(tp, 0, IMAGEBUTTON, LASERBUTTON);
deActivateControls(tp, IMAGEBUTTON, LASERBUTTON);
}
else {
forceValueToControls(tp, 1, APPLEWRITERBOX, APPLEWRITERBOX);
activateControls(tp, IMAGEBUTTON, LASERBUTTON);
i /= PRINTER_NUMBER_OF;
pushRadioButton(tp, IMAGEBUTTON+i, IMAGEBUTTON, LASERBUTTON);
}
/* Determine 'Exact dimensions'. */
i = iPaperSize & PIXELS_MASK;
if (i == PIXELS_EXACT)
pushCheckBox(tp, EXACTBOX);
}
/* Display scaling. */
setStringItemToInt(tp, STYLESCALENUM, descaledPrintRecord.printX[6]);
/* Determine correct default orientation for this paper type (not yet). */
pushRadioButton(tp, TALLBUTTON, TALLBUTTON, WIDEBUTTON);
deActivateControls(tp, WIDEBUTTON, WIDEBUTTON);
tp->pFltrProc = (ProcPtr)myStyleFilter;
tp->pItemProc = (ProcPtr)handleStyleItems;
tp->hPrintUsr = hPrint;
return(tp);
} /* myPrStlInit */
/* Job dialog initializer */
pascal TPPrDlg
myPrJobInit(hPrint)
THPrint hPrint;
{
TPPrDlg tp;
THPrint printRecordFromPreviousJob;
int resolution;
tp = allocatePrDialog();
(void)GetNewDialog(JOBDIALOG, tp, (WindowPtr)(-1L));
/* We cannot determine if the resources were found or not (IM I-413). */
/* Oops, IM doesn't say anything about 'hPrint': it may be full of zeros */
/* or from another driver and it is most likely unvalidated. ??? */
if ((printRecordFromPreviousJob = (THPrint)GetResource('PREC', 1)) == nil)
resolution = (*hPrint)->prStl.wDev & RES_MASK; /* use current one */
else {
LoadResource(printRecordFromPreviousJob);
resolution = (*printRecordFromPreviousJob)->prStl.wDev & RES_MASK;
HPurge(printRecordFromPreviousJob);
}
/* Default resolution: */
pushRadioButton(tp, DPI300BUTTON+resolution, DPI300BUTTON, DRAFTBUTTON);
/* Default is always "All pages" (according to IM II-158). */
pushRadioButton(tp, ALLBUTTON, ALLBUTTON, RANGEBUTTON);
/* Sheet feeding taken from current print record instead of the one from */
/* previous job. We want to suggest manual feeding for envelopes. */
if ((*hPrint)->prStl.feed == feedCut)
pushRadioButton(tp, MANUALBUTTON, AUTOMATICBUTTON, MANUALBUTTON);
else
pushRadioButton(tp, AUTOMATICBUTTON, AUTOMATICBUTTON, MANUALBUTTON);
setStringItemToInt(tp, COPIESNUM, 1); /* Always 1 according to IM II-158. */
tp->pFltrProc = (ProcPtr)myJobFilter;
tp->pItemProc = (ProcPtr)handleJobItems;
tp->hPrintUsr = hPrint;
return(tp);
} /* myPrJobInit */
/* Printing dialog supervisor function. */
pascal Boolean
myPrDlgMain(hPrint, pDlgInit)
THPrint hPrint;
ProcPtr pDlgInit;
{
TPPrDlg tp;
WindowPtr savePort;
HNoPurge(hPrint); /* hopefully it is not nil */
/* Call dialog init routine. */
asm {
subq.l #4,a7 ;; Room for function return
move.l hPrint,-(a7) ;; Pass handle to print record
move.l pDlgInit,a0 ;; Get addr of dialog init routine
jsr (a0) ;; It's a Pascal routine
move.l (a7)+,tp ;; pop return value
}
/* 'tp->pFltrProc' is set in init routine. */
/* 'tp->pItemProc' is set in init routine. */
tp->hPrintUsr = hPrint;
tp->fDone = FALSE;
tp->fDoIt = FALSE;
GetPort(&savePort);
SetPort(tp);
ShowWindow(tp);
while(!(tp->fDone)) {
int itemHit;
ProcPtr itemproc;
ModalDialog(tp->pFltrProc, &itemHit);
/* Reverse parameters on the call to pItemProc. */
/* The application is allowed to trap our 'pItemProc' and insert its own, */
/* so we must use the Pascal calling conventions here. */
itemproc = tp->pItemProc;
asm {
move.l tp,-(a7)
move.w itemHit,-(a7)
move.l itemproc,a0
jsr (a0)
}
}
SetPort(savePort);
{
Boolean tempDoIt;
tempDoIt = tp->fDoIt;
CloseDialog(tp);
DisposPtr(tp);
if (tempDoIt)
(void)myPrValidate(hPrint);
return(tempDoIt);
}
} /* myPrDlgMain */
/*
Validate/update a print record. Check all the fields for compatibility with our driver. This is
a three stage process. First, we check all fields to see whether they are within the bounds
which our driver can handle. If they are, we return FALSE (no change). If not, we obtain a copy
of the current default values from the printer resource file. Then we inspect these to see if
they are valid. If the default values in the printer resource file are valid, we use them,
update the user's print record, and return TRUE (changed). Otherwise, we fall back on default
values which we store in the code here. This three stage process provides some protection
against the user who attempts to adjust the print record using a resource editor and
screws up.
*/
pascal Boolean
myPrValidate(hPrint)
THPrint hPrint;
{
Boolean changedBecauseItWasNotValid;
HNoPurge(hPrint); /* hopefully it is not nil */
if (isValid(hPrint)) /* we accept it 'as is' */
changedBecauseItWasNotValid = FALSE;
else if (isCorrectableAndWasUpdated(hPrint)) /* we accept it after modifications */
changedBecauseItWasNotValid = TRUE;
else { /* it is garbage, get default one */
myPrintDefault(hPrint);
changedBecauseItWasNotValid = TRUE;
}
return changedBecauseItWasNotValid;
} /* myPrValidate */
pascal void
myPrJobMerge(hPrintSrc, hPrintDst)
THPrint hPrintSrc, hPrintDst;
{
HNoPurge(hPrintSrc); /* hopefully it is not nil */
HNoPurge(hPrintDst);
(void)myPrValidate(hPrintSrc); /* IM II-159. */
(void)myPrValidate(hPrintDst);
/* 'It then copies all the information set as a result of a job dialog...' IM II-159. */
(*hPrintDst)->prJob.bJDocLoop = (*hPrintSrc)->prJob.bJDocLoop;
(*hPrintDst)->prStl.wDev = (*hPrintSrc)->prStl.wDev;
(*hPrintDst)->prJob.iFstPage = (*hPrintSrc)->prJob.iFstPage;
(*hPrintDst)->prJob.iLstPage = (*hPrintSrc)->prJob.iLstPage;
(*hPrintDst)->prJob.iCopies = (*hPrintSrc)->prJob.iCopies;
(*hPrintDst)->prStl.feed = (*hPrintSrc)->prStl.feed;
/* '...it makes sure that all field of hPrintDst are */
/* internally self-consistent.' IM II-159. */
(void)myPrValidate(hPrintDst);
} /* myPrJobMerge */
pascal Boolean
myStyleFilter(theDialog, theEvent, itemHit)
TPPrDlg theDialog;
EventRecord *theEvent;
int *itemHit;
{
if (theEvent->what == updateEvt) {
if ((TPPrDlg)theEvent->message == theDialog)
frameButton(theDialog, OKBUTTON);
return FALSE;
}
else
if (theEvent->what == keyDown)
switch (theEvent->message & charCodeMask) {
case 0x03:
case 0x0D:
*itemHit = OKBUTTON; /* return and enter cause OK to be pressed */
return TRUE;
case 0x08: /* BS */
case 0x09: /* TAB */
case 0x1B: /* Clear */
case 0x1C: /* Left arrow */
case 0x1D: /* Right arrow */
case 0x1E: /* Up arrow */
case 0x1F: /* Down arrow */
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
return FALSE; /* editing keys and numbers processed as usual */
case '.':
if (theEvent->modifiers & cmdKey) {
/* Command-. = cancel */
*itemHit = CANCELBUTTON;
return TRUE;
}
/* else fall throug to default case: */
default:
if (theDialog->dlg.editField < LASTSTYLEITEM) {
SysBeep(8);
theEvent->what = nullEvent;
}
return FALSE;
} /* if & switch */
return FALSE;
} /* myStyleFilter */
pascal Boolean
myJobFilter(theDialog, theEvent, itemHit)
TPPrDlg theDialog;
EventRecord *theEvent;
int *itemHit;
{
if (theEvent->what == updateEvt) {
if ((TPPrDlg)theEvent->message == theDialog)
frameButton(theDialog, OKBUTTON);
return FALSE;
}
else
if (theEvent->what == keyDown)
switch (theEvent->message & charCodeMask) {
case 0x03:
case 0x0D:
*itemHit = OKBUTTON; /* return and enter cause OK to be pressed */
return TRUE;
case 0x08: /* BS */
case 0x09: /* TAB */
case 0x1B: /* Clear */
case 0x1C: /* Left arrow */
case 0x1D: /* Right arrow */
case 0x1E: /* Up arrow */
case 0x1F: /* Down arrow */
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
return FALSE; /* editing keys and numbers processed as usual */
case '.':
if (theEvent->modifiers & cmdKey) {
/* Command-. = cancel */
*itemHit = CANCELBUTTON;
return TRUE;
}
/* else fall throug to default case: */
default:
if (theDialog->dlg.editField < LASTJOBITEM) {
SysBeep(8);
theEvent->what = nullEvent;
}
return FALSE;
} /* if & switch */
return FALSE;
} /* myJobFilter */
/*
The next routine handles the style dialog. Two possibilities exist.
If the 'Cancel' button is hit then we signal quit. The print record is not changed.
If the 'OK' button is hit, we validate the user's print record.
*/
pascal void
handleStyleItems(tp, itemHit)
TPPrDlg tp;
int itemHit;
{
if (itemHit >= A4BUTTON && itemHit <= ENVELOPEBUTTON) {
pushRadioButton(tp, itemHit, A4BUTTON, OTHERBUTTON);
blankStringItem(tp, PAPERWIDTHNUM);
blankStringItem(tp, PAPERHEIGHTNUM);
blankStringItem(tp, MARGINTOPNUM);
blankStringItem(tp, MARGINLEFTNUM);
blankStringItem(tp, MARGINBOTTOMNUM);
blankStringItem(tp, MARGINRIGHTNUM);
blankStringItem(tp, RESVNUM);
blankStringItem(tp, RESHNUM);
activateControls(tp, APPLEWRITERBOX, APPLEWRITERBOX);
forceValueToControls(tp, 0, APPLEWRITERBOX, APPLEWRITERBOX); /* should be the previous user selection ??? */
forceValueToControls(tp, 0, IMAGEBUTTON, LASERBUTTON);
deActivateControls(tp, IMAGEBUTTON, LASERBUTTON);
}
else if (itemHit >= IMAGEBUTTON && itemHit <= LASERBUTTON)
pushRadioButton(tp, itemHit, IMAGEBUTTON, LASERBUTTON);
else if (itemHit >= TALLBUTTON && itemHit <= WIDEBUTTON)
pushRadioButton(tp, itemHit, TALLBUTTON, WIDEBUTTON);
else if (itemHit == EXACTBOX)
pushCheckBox(tp, itemHit);
else if (itemHit == APPLEWRITERBOX) {
if (pushCheckBox(tp, itemHit)) {
activateControls(tp, IMAGEBUTTON, LASERBUTTON);
pushRadioButton(tp, IMAGEBUTTON, IMAGEBUTTON, LASERBUTTON); /* should be the previous user selection ??? */
}
else {
forceValueToControls(tp, 0, IMAGEBUTTON, LASERBUTTON);
deActivateControls(tp, IMAGEBUTTON, LASERBUTTON);
}
}
else if (itemHit == OTHERBUTTON) {
TPrint Print;
TPPrint pPrint;
/* Default values for 'other' numeric fields from our standard sizes. */
pPrint = &Print;
setPaperSizeFieldsInPrintRecord(tp, &pPrint);
setOtherPaperSizeInDialog(tp, &pPrint);
}
else if ((itemHit == STYLEHELPBUTTON) || (itemHit == HPICON)) {
(void)Alert(STYLEHELPDIALOG, nil);
}
else if (itemHit == OKBUTTON) {
TPPrint pPrint;
HLock(tp->hPrintUsr);
pPrint = *(tp->hPrintUsr);
/* We should not overwrite everything in 'tp->hPrintUsr', instead, */
/* we trust our validation procedure to correct improper values. */
if (controlIsOn(tp, OTHERBUTTON)) {
/* Paper rectangle. */
pPrint->rPaper.top = 0;
pPrint->rPaper.left = 0;
pPrint->rPaper.bottom = getStringItemAsInt(tp, PAPERHEIGHTNUM);
pPrint->rPaper.right = getStringItemAsInt(tp, PAPERWIDTHNUM);
OffsetRect(
&(pPrint->rPaper),
- getStringItemAsInt(tp, MARGINLEFTNUM),
- getStringItemAsInt(tp, MARGINTOPNUM)
);
/* Page rectangle. */
pPrint->prInfo.rPage.top = 0;
pPrint->prInfo.rPage.left = 0;
pPrint->prInfo.rPage.bottom = pPrint->rPaper.bottom - getStringItemAsInt(tp, MARGINBOTTOMNUM);
pPrint->prInfo.rPage.right = pPrint->rPaper.right - getStringItemAsInt(tp, MARGINRIGHTNUM);
pPrint->prInfo.iVRes = getStringItemAsInt(tp, RESVNUM);
pPrint->prInfo.iHRes = getStringItemAsInt(tp, RESHNUM);
pPrint->prInfoPT = pPrint->prInfo;
/* Physical paper size. */
pPrint->prStl.iPageV =
(int)(
(long)getStringItemAsInt(tp, PAPERHEIGHTNUM)
* (long)iPrPgFract
/ (long)pPrint->prInfo.iVRes
);
pPrint->prStl.iPageH =
(int)(
(long)getStringItemAsInt(tp, PAPERWIDTHNUM)
* (long)iPrPgFract
/ (long)pPrint->prInfo.iHRes
);
}
else
setPaperSizeFieldsInPrintRecord(tp, tp->hPrintUsr);
/* This won't set anything if resource 'PREC' 4 is missing or malformed. ??? */
/* Scale all rectangles accrding to 'Scale...' field. */
{
Rect tr1, tr2;
tr1.top = 0;
tr1.left = 0;
tr1.bottom = tr1.right = 100;
tr2.top = 0;
tr2.left = 0;
tr2.bottom = tr2.right
= pPrint->printX[6] = getStringItemAsInt(tp, STYLESCALENUM);
MapRect(&(pPrint->rPaper), &tr1, &tr2);
MapRect(&(pPrint->prInfo.rPage), &tr1, &tr2);
ScalePt(&(pPrint->prStl.iPageV), &tr1, &tr2); /* V&H = Point ! */
}
/*** if (controlIsOn(tp, WIDEBUTTON)) {
int temp;
flipRect(&pPrint->prInfo.rPage);
flipRect(&pPrint->rPaper);
flipRect(&pPrint->prInfoPT.rPage);
temp = pPrint->prStl.iPageV;
pPrint->prStl.iPageV = (*tp->hPrintUsr)->prStl.iPageH;
pPrint->prStl.iPageH = temp;
}
***/
HUnlock(tp->hPrintUsr);
tp->fDone = TRUE;
tp->fDoIt = TRUE;
} /* if OK */
else if (itemHit == CANCELBUTTON) {
tp->fDone = TRUE;
tp->fDoIt = FALSE;
} /* if Cancel */
} /* handleStyleItems */
void
setPaperSizeFieldsInPrintRecord(tp, hPrint)
TPPrDlg tp;
THPrint hPrint;
{
int temp1, temp2, temp3;
temp1 = whichRadioButton(tp, A4BUTTON, ENVELOPEBUTTON);
if (temp1 < 0)
temp1 = PAPER_DEFAULT;
if (controlIsOn(tp, APPLEWRITERBOX)) {
temp2 = whichRadioButton(tp, IMAGEBUTTON, LASERBUTTON);
temp2 *= PRINTER_NUMBER_OF;
if (temp2 < 0)
temp2 = PRINTER_DEFAULT;
}
else {
temp2 = PRINTER_HPDESKJET;
}
if (controlIsOn(tp, EXACTBOX))
temp3 = PIXELS_EXACT;
else
temp3 = PIXELS_BEAUTIFUL;
(void)updatePaperSize(hPrint, temp1+temp2+temp3);
} /* setPaperSizeFieldsInPrintRecord */
void
setOtherPaperSizeInDialog(tp, hPrint)
TPPrDlg tp;
THPrint hPrint;
{
setStringItemToInt(tp, PAPERWIDTHNUM, ((*hPrint)->rPaper.right - (*hPrint)->rPaper.left));
setStringItemToInt(tp, PAPERHEIGHTNUM, ((*hPrint)->rPaper.bottom - (*hPrint)->rPaper.top));
setStringItemToInt(tp, MARGINTOPNUM, - (*hPrint)->rPaper.top);
setStringItemToInt(tp, MARGINLEFTNUM, - (*hPrint)->rPaper.left);
setStringItemToInt(tp, MARGINBOTTOMNUM, ((*hPrint)->rPaper.bottom - (*hPrint)->prInfo.rPage.bottom));
setStringItemToInt(tp, MARGINRIGHTNUM, ((*hPrint)->rPaper.right - (*hPrint)->prInfo.rPage.right));
setStringItemToInt(tp, RESVNUM, (*hPrint)->prInfo.iVRes);
setStringItemToInt(tp, RESHNUM, (*hPrint)->prInfo.iHRes);
pushRadioButton(tp, OTHERBUTTON, A4BUTTON, OTHERBUTTON);
forceValueToControls(tp, 0, APPLEWRITERBOX, APPLEWRITERBOX);
deActivateControls(tp, APPLEWRITERBOX, APPLEWRITERBOX);
forceValueToControls(tp, 0, IMAGEBUTTON, LASERBUTTON);
deActivateControls(tp, IMAGEBUTTON, LASERBUTTON);
} /* setOtherPaperSizeInDialog */
pascal void
handleJobItems(tp, itemHit)
TPPrDlg tp;
int itemHit;
{
if (itemHit >= DPI300BUTTON && itemHit <= DRAFTBUTTON)
pushRadioButton(tp, itemHit, DPI300BUTTON, DRAFTBUTTON);
else if ((itemHit >= ALLBUTTON) && (itemHit <= RANGEBUTTON))
pushRadioButton(tp, itemHit, ALLBUTTON, RANGEBUTTON);
else if ((itemHit >= FROMNUM) && (itemHit <= TONUM)) /* force 'From' button when page range is typed */
pushRadioButton(tp, RANGEBUTTON, ALLBUTTON, RANGEBUTTON);
else if ((itemHit >= AUTOMATICBUTTON) && (itemHit <= MANUALBUTTON))
pushRadioButton(tp, itemHit, AUTOMATICBUTTON, MANUALBUTTON);
else if (itemHit == JOBHELPBUTTON) {
(void)Alert(JOBHELPDIALOG, nil);
}
else if (itemHit == OKBUTTON) {
ptXprintGlobals xPrintGlobals;
xPrintGlobals = GET_XPRINT_GLOBALS;
/* If option key is held down, set permanent spool file flag. */
{
EventRecord tempEvent;
(void)EventAvail(everyEvent, &tempEvent);
if (tempEvent.modifiers & optionKey) {
xPrintGlobals->spoolFileIsNamedAndPermanent = TRUE;
}
else {
xPrintGlobals->spoolFileIsNamedAndPermanent = FALSE;
}
} /* if option */
/* Spool file is not named -- permanent or temporary. */
xPrintGlobals->spoolFileAlreadyNamed = FALSE;
/* Resolution: */
{
int temp;
temp = whichRadioButton(tp, DPI300BUTTON, DRAFTBUTTON);
if (temp < 0)
temp = RES_DEFAULT;
if (temp == RES_DRAFT)
(*(tp->hPrintUsr))->prJob.bJDocLoop = bDraftLoop;
else
(*(tp->hPrintUsr))->prJob.bJDocLoop = bSpoolLoop;
(*(tp->hPrintUsr))->prStl.wDev = iDevCItoh + temp;
}
/* Page range: */
if (controlIsOn(tp, ALLBUTTON)) {
(*(tp->hPrintUsr))->prJob.iFstPage = iPrPgFst;
(*(tp->hPrintUsr))->prJob.iLstPage = iPrPgMax;
}
else {
int theInt;
theInt = getStringItemAsInt(tp, FROMNUM);
(*(tp->hPrintUsr))->prJob.iFstPage =
( ((theInt<iPrPgFst)||(theInt>iPrPgMax)) ? iPrPgFst : theInt );
theInt = getStringItemAsInt(tp, TONUM);
(*(tp->hPrintUsr))->prJob.iLstPage =
( ((theInt<iPrPgFst)||(theInt>iPrPgMax)) ? iPrPgMax : theInt );
}
{
int theInt;
theInt = getStringItemAsInt(tp, COPIESNUM);
(*(tp->hPrintUsr))->prJob.iCopies = ( ((theInt<1)) ? 1 : theInt );
}
(*(tp->hPrintUsr))->printX[7] = getStringItemAsInt(tp, JOBSCALENUM);
if (controlIsOn(tp, MANUALBUTTON))
(*(tp->hPrintUsr))->prStl.feed = feedCut;
else
(*(tp->hPrintUsr))->prStl.feed = feedMechCut;
tp->fDone = TRUE;
tp->fDoIt = TRUE;
} /* if OK */
else if (itemHit == CANCELBUTTON) {
tp->fDone = TRUE;
tp->fDoIt = FALSE;
}
} /* handleJobItems */
TPPrDlg
allocatePrDialog()
{
TPPrDlg thePointer;
if ((thePointer = (TPPrDlg)NewPtr((long)(sizeof(TPrDlg) + 24))) == nil) /* six extra longs ??? */
SysError(25);
return(thePointer);
} /* allocatePrDialog */
#include "dialog_item_handling.c"
void
blankStringItem(theDialog, theItem)
TPPrDlg theDialog;
int theItem;
{
int itemtype;
Handle itemhandle;
Rect itemrect;
Str255 numAsString;
if (theItem <= 0)
return;
numAsString[0] = 0;
GetDItem(theDialog, theItem, &itemtype, &itemhandle, &itemrect);
itemtype &= ~itemDisable; /* regardless of whether item is disabled or not */
if ((itemtype == statText) || (itemtype == editText))
SetIText(itemhandle, numAsString);
} /* blankStringItem */
Boolean
isValid(hPrint)
THPrint hPrint;
{
if ((*hPrint)->iPrVersion != PRINTING_MANAGER_VERSION) goto retFalse;
if ((*hPrint)->prInfo.iDev != 0) goto retFalse;
if (!(((*hPrint)->prInfo.iVRes == 72)
|| ((*hPrint)->prInfo.iVRes == 75))) goto retFalse;
if (!(((*hPrint)->prInfo.iHRes == 72)
|| ((*hPrint)->prInfo.iHRes == 75)
|| ((*hPrint)->prInfo.iHRes == 80))) goto retFalse;
if ((*hPrint)->prInfo.rPage.top != 0) goto retFalse;
if ((*hPrint)->prInfo.rPage.left != 0) goto retFalse;
/* Paper size should be checked: rPaper, prInfo.rPage, prStl.iPageV/H. */
if (!(((*hPrint)->prStl.feed == feedCut)
|| ((*hPrint)->prStl.feed == feedMechCut))) goto retFalse;
if (((*hPrint)->prStl.wDev < (iDevCItoh+RES_300))
|| ((*hPrint)->prStl.wDev > (iDevCItoh+RES_DRAFT))) goto retFalse;
/* if prInfoPT (print time) <> prInfo then goto retFalse ??? */
/* prXInfo ??? */
if ((*hPrint)->prJob.bJDocLoop == bDraftLoop)
if ((*hPrint)->prStl.wDev != (iDevCItoh+RES_DRAFT)) goto retFalse;
/* Scaling factors. */
if (((*hPrint)->printX[6] < 25)
|| ((*hPrint)->printX[6] > 400)) goto retFalse;
if (((*hPrint)->printX[7] < 25)
|| ((*hPrint)->printX[7] > 400)) goto retFalse;
return TRUE;
retFalse:
return FALSE;
} /* isValid */
Boolean
isCorrectableAndWasUpdated(hPrint)
THPrint hPrint;
{
(*hPrint)->iPrVersion = PRINTING_MANAGER_VERSION;
(*hPrint)->prInfo.iDev = 0;
/* Update sizes and resolutions. ??? */
if ((*hPrint)->prInfo.rPage.top != 0) goto retFalse;
if ((*hPrint)->prInfo.rPage.left != 0) goto retFalse;
if (!(((*hPrint)->prStl.feed == feedCut)
|| ((*hPrint)->prStl.feed == feedMechCut)))
(*hPrint)->prStl.feed = feedMechCut;
if (((*hPrint)->prStl.wDev < (iDevCItoh+RES_300))
|| ((*hPrint)->prStl.wDev > (iDevCItoh+RES_DRAFT)))
(*hPrint)->prStl.wDev = iDevCItoh+RES_DEFAULT;
/* Calculate banding & print time info ??? */
/* prXInfo ??? */
if ((*hPrint)->prJob.bJDocLoop == bDraftLoop)
if ((*hPrint)->prStl.wDev != (iDevCItoh+RES_DRAFT))
(*hPrint)->prStl.wDev = iDevCItoh+RES_DRAFT;
/* Scaling factors. */
if (((*hPrint)->printX[6] < 25)
|| ((*hPrint)->printX[6] > 400))
(*hPrint)->printX[6] = 100;
if (((*hPrint)->printX[7] < 25)
|| ((*hPrint)->printX[7] > 400))
(*hPrint)->printX[7] = 100;
return(TRUE);
retFalse:
return(FALSE);
} /* isCorrectableAndWasUpdated */
/*** This might be useful when 'Wide' orientation is implemented.
flipRect(rect)
Rect rect;
{
asm {
move.l rect,a0
move.l (a0),d0
swap d0
move.l d0,(a0)+
move.l (a0),d0
swap d0
move.l d0,(a0)
}
} ***/
/*
This function fills a print record with defaults, using coded values.
These values default to 75 dpi spool printing with max. print area.
*/
void
mkDefault(hPrint)
THPrint hPrint;
{
(*hPrint)->iPrVersion = PRINTING_MANAGER_VERSION;
(*hPrint)->prInfo.iDev = 0; /* ? screen = 0 (as in Imagewriter) */
/* This information normally comes from our paper size resource 'PREC' 4. */
(*hPrint)->prInfo.iVRes = 75;
(*hPrint)->prInfo.iHRes = 75;
(*hPrint)->rPaper.top = -53;
(*hPrint)->rPaper.left = -17;
(*hPrint)->rPaper.bottom = 823;
(*hPrint)->rPaper.right = 602;
(*hPrint)->prInfo.rPage.top = 0;
(*hPrint)->prInfo.rPage.left = 0;
(*hPrint)->prInfo.rPage.bottom = 791;
(*hPrint)->prInfo.rPage.right = 596;
(*hPrint)->prStl.iPageV = 1403;
(*hPrint)->prStl.iPageH = 992;
(*hPrint)->prStl.feed = feedMechCut;
/* These values are initialized by dialogs or only here. */
(*hPrint)->prStl.wDev = iDevCItoh + RES_DEFAULT;
(*hPrint)->prStl.bPort = 0; /* xPrintGlobals->currentSettings.port ??? */
(*hPrint)->prInfoPT = (*hPrint)->prInfo;
(*hPrint)->prXInfo.iRowBytes = 0;
(*hPrint)->prXInfo.iBandV = 0;
(*hPrint)->prXInfo.iBandH = 0;
(*hPrint)->prXInfo.iDevBytes = 4;
/* This is to satisfy applications which want to allocate */
/* the banding buffer themselves. */
/* We need more bytes than this _int_ can support. */
(*hPrint)->prXInfo.iBands = 0;
(*hPrint)->prXInfo.bPatScale = 0;
(*hPrint)->prXInfo.bULThick = 0;
(*hPrint)->prXInfo.bULOffset = 0;
(*hPrint)->prXInfo.bULShadow = 0;
(*hPrint)->prXInfo.scan = scanLR;
(*hPrint)->prXInfo.bXInfoX = 0;
(*hPrint)->prJob.iFstPage = 1;
(*hPrint)->prJob.iLstPage = iPrPgMax;
(*hPrint)->prJob.iCopies = 1;
(*hPrint)->prJob.bJDocLoop = bSpoolLoop;
(*hPrint)->prJob.fFromUsr = TRUE;
(*hPrint)->prJob.pIdleProc = nil;
(*hPrint)->prJob.pFileName = nil;
(*hPrint)->prJob.iFileVol = 0;
(*hPrint)->prJob.bFileVers = 0;
(*hPrint)->prJob.bJobX = 0;
(*hPrint)->printX[0] =
(*hPrint)->printX[1] =
(*hPrint)->printX[2] =
(*hPrint)->printX[3] =
(*hPrint)->printX[4] =
(*hPrint)->printX[5] =
(*hPrint)->printX[8] =
(*hPrint)->printX[9] =
(*hPrint)->printX[10] =
(*hPrint)->printX[11] =
(*hPrint)->printX[12] =
(*hPrint)->printX[13] =
(*hPrint)->printX[14] =
(*hPrint)->printX[15] =
(*hPrint)->printX[16] =
(*hPrint)->printX[17] =
(*hPrint)->printX[18] = 0;
/* Scaling factors. */
(*hPrint)->printX[6] = 100;
(*hPrint)->printX[7] = 100;
}
Boolean
updatePaperSize(hPrint, iPaperSize)
THPrint hPrint;
int iPaperSize;
{
htAllSizesInfo hSizes;
if ((hSizes = (htAllSizesInfo)GetResource('PREC', 4)) == nil)
return(FALSE);
LoadResource(hSizes);
if ((iPaperSize < 0) || (iPaperSize > (*hSizes)->iNumberOfItems))
return(FALSE);
(*hPrint)->prInfo.iVRes = (*hSizes)->sSizeInfo[iPaperSize].iVRes;
(*hPrint)->prInfo.iHRes = (*hSizes)->sSizeInfo[iPaperSize].iHRes;
(*hPrint)->rPaper = (*hSizes)->sSizeInfo[iPaperSize].rPaper;
(*hPrint)->prInfo.rPage = (*hSizes)->sSizeInfo[iPaperSize].rPage;
(*hPrint)->prStl.iPageV = (*hSizes)->sSizeInfo[iPaperSize].iPageV;
(*hPrint)->prStl.iPageH = (*hSizes)->sSizeInfo[iPaperSize].iPageH;
(*hPrint)->prStl.feed = (*hSizes)->sSizeInfo[iPaperSize].feed;
(*hPrint)->prInfoPT = (*hPrint)->prInfo;
return(TRUE);
} /* updatePaperSize */
int
whichPaperSize(hPrint)
THPrint hPrint;
{
htAllSizesInfo hSizes;
int iPaperSize;
if ((hSizes = (htAllSizesInfo)GetResource('PREC', 4)) == nil)
return(-1);
LoadResource(hSizes);
for (iPaperSize = 0; iPaperSize < (*hSizes)->iNumberOfItems; iPaperSize++)
if ( ((*hPrint)->prInfo.iVRes == (*hSizes)->sSizeInfo[iPaperSize].iVRes)
&& ((*hPrint)->prInfo.iHRes == (*hSizes)->sSizeInfo[iPaperSize].iHRes)
&& ((*hPrint)->rPaper.top == (*hSizes)->sSizeInfo[iPaperSize].rPaper.top)
&& ((*hPrint)->rPaper.left == (*hSizes)->sSizeInfo[iPaperSize].rPaper.left)
&& ((*hPrint)->rPaper.bottom == (*hSizes)->sSizeInfo[iPaperSize].rPaper.bottom)
&& ((*hPrint)->rPaper.right == (*hSizes)->sSizeInfo[iPaperSize].rPaper.right)
&& ((*hPrint)->prInfo.rPage.top == (*hSizes)->sSizeInfo[iPaperSize].rPage.top)
&& ((*hPrint)->prInfo.rPage.left == (*hSizes)->sSizeInfo[iPaperSize].rPage.left)
&& ((*hPrint)->prInfo.rPage.bottom == (*hSizes)->sSizeInfo[iPaperSize].rPage.bottom)
&& ((*hPrint)->prInfo.rPage.right == (*hSizes)->sSizeInfo[iPaperSize].rPage.right)
&& ((*hPrint)->prStl.iPageV == (*hSizes)->sSizeInfo[iPaperSize].iPageV)
&& ((*hPrint)->prStl.iPageH == (*hSizes)->sSizeInfo[iPaperSize].iPageH) )
return(iPaperSize);
return(-1);
} /* whichPaperSize */